﻿using Dapper;
using JX.Core;
using JX.Core.Entity;
using JX.Infrastructure;
using JX.Infrastructure.Common;
using JX.Infrastructure.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace JX.Application
{
	public partial class NodesServiceAppDapper : ServiceAppDapper<NodesEntity>, INodesServiceAppDapper
	{
		#region 仓储接口
		private int orderId;
		private int rootId;
		private readonly IRolesServiceAppDapper _RolesServiceApp;
		private readonly IUserGroupsServiceAppDapper _UserGroupsServiceApp;
		private readonly IModelsServiceAppDapper _ModelsServiceApp;
		private readonly ICommonInfoServiceAppDapper _CommonInfoServiceApp;
		private readonly INodesTemplateRepositoryDapper _NodesTemplateRepository;
		private readonly INodesModelTemplateRepositoryDapper _NodesModelTemplateRepository;
		private readonly ILogRepositoryDapper _LogRepository;
		/// <summary>
		/// 构造器注入
		/// </summary>
		/// <param name="repository"></param>
		/// <param name="nodesTemplateRepository"></param>
		/// <param name="NodesModelTemplateRepository"></param>
		/// <param name="logRepository"></param>
		/// <param name="CommonInfoServiceApp"></param>
		/// <param name="RolesServiceApp"></param>
		/// <param name="UserGroupsServiceApp"></param>
		/// <param name="ModelsServiceApp"></param>
		public NodesServiceAppDapper(INodesRepositoryDapper repository,
			INodesTemplateRepositoryDapper nodesTemplateRepository,
			INodesModelTemplateRepositoryDapper NodesModelTemplateRepository,
			ILogRepositoryDapper logRepository,
			ICommonInfoServiceAppDapper CommonInfoServiceApp,
			IRolesServiceAppDapper RolesServiceApp,
			IUserGroupsServiceAppDapper UserGroupsServiceApp,
			IModelsServiceAppDapper ModelsServiceApp) : base(repository)
		{
			m_repository = repository;
			_NodesTemplateRepository = nodesTemplateRepository;
			_NodesModelTemplateRepository = NodesModelTemplateRepository;
			_LogRepository = logRepository;
			_CommonInfoServiceApp = CommonInfoServiceApp;
			_RolesServiceApp = RolesServiceApp;
			_UserGroupsServiceApp = UserGroupsServiceApp;
			_ModelsServiceApp = ModelsServiceApp;
		}
		#endregion

		#region 得到实体类
		/// <summary>
		/// 获取节点信息，不包含扩展信息
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public NodesEntity GetNodeById(int nodeId)
		{
			if ((nodeId != -2) && (nodeId <= 0))
			{
				return new NodesEntity();
			}
			var entity = m_repository.Get(p => p.NodeID == nodeId);
			return entity;
		}
		/// <summary>
		/// 从缓存中得到节点信息，不包含扩展信息
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public NodesEntity GetCacheNodeById(int nodeId)
		{
			if ((nodeId != -2) && (nodeId <= 0))
			{
				return new NodesEntity();
			}
			string key = "CK_Content_NodeInfo_NodeId_" + nodeId.ToString();
			var nodeById = CacheHelper.CacheServiceProvider.Get<NodesEntity>(key);
			if (nodeById == null)
			{
				nodeById = GetNodeById(nodeId);
				CacheHelper.CacheServiceProvider.AddOrUpdate(key, nodeById);
			}
			return nodeById;
		}
		/// <summary>
		/// 按标识符获取节点，不包含扩展信息
		/// </summary>
		/// <param name="identifier"></param>
		/// <returns></returns>
		public NodesEntity GetNodeByIdentifier(string identifier)
		{
			if (string.IsNullOrEmpty(identifier))
			{
				return new NodesEntity();
			}
			var entity = m_repository.Get(p => p.NodeIdentifier == identifier);
			return entity;
		}
		/// <summary>
		/// 按子域名获取节点，不包含扩展信息
		/// </summary>
		/// <param name="subDomain"></param>
		/// <returns></returns>
		public NodesEntity GetNodeBySubDomain(string subDomain)
		{
			if (string.IsNullOrEmpty(subDomain))
			{
				return new NodesEntity();
			}
			var entity = m_repository.Get(p => p.SubDomain == subDomain);
			return entity;
		}
		/// <summary>
		/// 通过指定ParentID下的，指定NodeID的对应节点信息
		/// </summary>
		/// <param name="parentId"></param>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public NodesEntity GetParentNodeByNodeId(int parentId, int nodeId)
		{
			var entity = m_repository.Get(p => p.ParentID == parentId && p.NodeID == nodeId);
			return entity;
		}
		/// <summary>
		/// 获取根节点信息，不包含扩展信息
		/// </summary>
		/// <param name="parentPath">父节点路径(0,1,2,3)</param>
		/// <returns></returns>
		public NodesEntity GetRootNodeByParentPath(string parentPath)
		{
			if (!string.IsNullOrEmpty(parentPath))
			{
				string[] strArray = parentPath.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				for (int i = 0; i < strArray.Length; i++)
				{
					int nodeId = DataConverter.CLng(strArray[i]);
					if (nodeId > 0)
					{
						NodesEntity cacheNodeById = GetCacheNodeById(nodeId);
						if (cacheNodeById.ParentID == 0)
						{
							return cacheNodeById;
						}
					}
				}
			}
			return new NodesEntity();
		}
		/// <summary>
		/// 获取根节点信息，不包含扩展信息
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <returns></returns>
		public NodesEntity GetRootNodeInfo(NodesEntity nodeInfo)
		{
			if (nodeInfo.ParentID != 0)
			{
				while (nodeInfo.ParentID != 0)
				{
					nodeInfo = GetNodeById(nodeInfo.ParentID.ToInt32());
				}
				return nodeInfo;
			}
			return nodeInfo;
		}
		#endregion

		#region 得到实体类列表
		/// <summary>
		/// 获取所有的节点列表（包含容器栏目、专题栏目、单页节点和外链），并添加 '所有栏目'为根节点
		/// </summary>
		/// <param name="nodeType">节点类型</param>
		/// <param name="isShowArchiving">是否显示归档类型的节点</param>
		/// <param name="isAddAll">是否添加'所有栏目'为根节点</param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeList(NodeType nodeType = NodeType.None, bool isShowArchiving = false, bool isAddAll = false)
		{
			Expression<Func<NodesEntity, bool>> predicate = p => true;
			if (nodeType != NodeType.None)
			{
				predicate = predicate.And(p => p.NodeType == (int)nodeType);
			}
			if (!isShowArchiving)
			{
				predicate = predicate.And(p => p.PurviewType != 3);
			}
			
			var nodesList = GetList(predicate,m=>m.OrderBy(item=>item.RootID).ThenBy(item=>item.OrderSort)).AsList();
			if (isAddAll)
			{
				NodesEntity item = new NodesEntity();
				item.NodeName = "所有栏目";
				item.NodeID = -1;
				item.Depth = 0;
				item.ParentPath = "0";
				item.NextID = 0;
				item.Child = 0;
				item.NodeType = (int)(NodeType.Container);
				item.NodeDir = string.Empty;
				nodesList.Insert(0, item);
			}
			return nodesList;
		}
		/// <summary>
		/// 获取节点列表包括归档节点
		/// </summary>
		/// <param name="nodesId">多个ID用“,”分割</param>
		/// <param name="isShowArchiving">是否显示归档节点</param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeList(string nodesId, bool isShowArchiving = false)
		{
			if (!DataValidator.IsValidId(nodesId))
			{
				return new List<NodesEntity>();
			}
			Expression<Func<NodesEntity, bool>> predicate = p => true;
			if (!string.IsNullOrEmpty(nodesId))
			{
				var arrNodeID = nodesId.Split(',');
				predicate = predicate.And(p => arrNodeID.Contains(p.NodeID.ToString()));
			}
			if (!isShowArchiving)
			{
				predicate = predicate.And(p => p.PurviewType != 3);
			}
			var nodesList = GetList(predicate, m => m.OrderBy(item => item.RootID).ThenBy(item => item.OrderSort)).AsList();
			return nodesList;
		}

		/// <summary>
		///  获取存档内容节点列表
		/// </summary>
		/// <param name="isShowArchiving"></param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodesListByArchiving(bool isShowArchiving)
		{
			return GetNodeList(NodeType.None, isShowArchiving, false);
		}
		/// <summary>
		/// 获取所有节点类型为容器栏目的节点列表，并添加 '所有栏目'为根节点。
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeListByContainer()
		{
			return GetNodeList(NodeType.Container, true, true);
		}
		/// <summary>
		/// 按父节点ID获取子节点列表
		/// </summary>
		/// <param name="parentId"></param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodesListByParentId(int parentId)
		{
			Expression<Func<NodesEntity, bool>> predicate = p => p.ParentID == parentId;
			var nodesList = GetList(predicate, m => m.OrderBy(item => item.RootID).ThenBy(item => item.OrderSort)).AsList();
			return nodesList;
		}
		/// <summary>
		/// 按根节点获取第一级子节点列表
		/// </summary>
		/// <param name="rootId"></param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodesListByRootId(int rootId)
		{
			Expression<Func<NodesEntity, bool>> predicate = p => p.RootID == rootId && p.ParentID > 0;
			var nodesList = GetList(predicate, m => m.OrderBy(item => item.OrderSort)).AsList();
			return nodesList;
		}
		/// <summary>
		/// 获取指定节点ID集的节点列表
		/// </summary>
		/// <param name="arrChildId">多个ID用“,”分割</param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodesListInArrChildId(string arrChildId)
		{
			if (!DataValidator.IsValidId(arrChildId))
			{
				return new List<NodesEntity>();
			}
			return GetNodeList(arrChildId, true);
		}
		/// <summary>
		/// 按父节点路径获取子节点列表，按Depth排序。
		/// </summary>
		/// <param name="parentPath">多个ID用“,”分割</param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodesListInParentPath(string parentPath)
		{
			if (!DataValidator.IsValidId(parentPath))
			{
				return new List<NodesEntity>();
			}
			Expression<Func<NodesEntity, bool>> predicate = p => true;
			if (!string.IsNullOrEmpty(parentPath))
			{
				var arrNodeID = parentPath.Split(',');
				predicate = predicate.And(p => arrNodeID.Contains(p.NodeID.ToString()));
			}
			var nodesList = GetList(predicate, m => m.OrderBy(item => item.Depth)).AsList();
			return nodesList;
		}
		/// <summary>
		/// 获取指定用户组、指定权限码、可匿名访问的节点列表。
		/// 栏目权限。0--开放栏目  1--半开放栏目  2--认证栏目
		/// </summary>
		/// <param name="groupId">会员组ID</param>
		/// <param name="operateCode"></param>
		/// <returns></returns>
		public IList<NodesEntity> GetAnonymousNodeId(int groupId, string operateCode)
		{
			string strCommand = "SELECT * FROM Nodes WHERE NodeId IN (SELECT DISTINCT NodeId FROM GroupNodePermissions WHERE GroupId = @GroupId AND OperateCode = @OperateCode) AND PurviewType <> 3  ORDER BY NodeId";
			return GetListBySQL<NodesEntity>(strCommand, new { GroupId= groupId , OperateCode = operateCode }).AsList();
		}
		/// <summary>
		/// 获取所有绑定了内容模型的节点列表
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetContentNodeList()
		{
			string strSql = "SELECT * FROM Nodes WHERE Nodetype = @NodeType AND NodeID IN (SELECT NodeID FROM NodesModelTemplate WHERE modelID IN (select ModelID FROM Model WHERE ModelType = 1)) ORDER BY RootID, OrderSort ASC";
			return GetListBySQL<NodesEntity>(strSql, new { NodeType = NodeType.Container}).AsList();
		}
		/// <summary>
		/// 获取所有绑定了商品模型的节点列表
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetShopNodeList()
		{
			string strSql = "SELECT * FROM Nodes WHERE Nodetype = @NodeType AND NodeID IN (SELECT NodeID FROM NodesModelTemplate WHERE modelID IN (select ModelID FROM Model WHERE ModelType = 2)) ORDER BY RootID, OrderSort ASC";
			return GetListBySQL<NodesEntity>(strSql, new { NodeType = NodeType.Container }).AsList();
		}
		/// <summary>
		/// 按父节点获取商城节点列表
		/// </summary>
		/// <param name="parentId"></param>
		/// <returns></returns>
		public IList<NodesEntity> GetShopNodeListByParentId(int parentId)
		{
			string strSql = "SELECT * FROM Nodes WHERE ParentID = @ParentID and Nodetype = @NodeType AND NodeID IN (SELECT NodeID FROM NodesModelTemplate WHERE modelID IN (select ModelID FROM Model WHERE ModelType = 2)) ORDER BY RootID, OrderSort ASC";
			return GetListBySQL<NodesEntity>(strSql, new { ParentID = parentId,NodeType = NodeType.Container }).AsList();
		}

		/// <summary>
		/// 获取父节点下所有节点的下拉选择树
		/// </summary>
		/// <param name="parentID"></param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeNameByParentID(int parentID)
		{
			return NodeTreeItems(GetNodeList(GetNodeById(parentID).ArrChildID, true));
		}
		/// <summary>
		/// 获取节点类型为容器节点的下拉选择树
		/// </summary>
		/// <param name="isShowArchiving">是否显示归档节点</param>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeNameForContainerItems(bool isShowArchiving = false)
		{
			return NodeTreeItems(GetNodeList(NodeType.Container, isShowArchiving, false));
		}
		/// <summary>
		/// 获取所有节点的下拉选择树（包含容器栏目、专题栏目、单页节点和外链）
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeNameForItems()
		{
			return NodeTreeItems(GetNodeList());
		}
		/// <summary>
		/// 获取所有节点的下拉选择树（不包含外链节点）
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeNameForItemsExceptOutLinks()
		{
			IList<NodesEntity> nodesList = GetNodeList();
			IList<NodesEntity> nodeList = new List<NodesEntity>();
			foreach (NodesEntity info in nodesList)
			{
				if (info.NodeType != (int)(NodeType.Link))
				{
					nodeList.Add(info);
				}
			}
			return NodeTreeItems(nodeList);
		}
		/// <summary>
		/// 获取内容节点下拉选择树
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeNameForContent()
		{
			IList<NodesEntity> nodesList = GetContentNodeList();
			return NodeTreeItems(nodesList);
		}
		/// <summary>
		/// 获取商城节点下拉选择树
		/// </summary>
		/// <returns></returns>
		public IList<NodesEntity> GetNodeNameForShop()
		{
			IList<NodesEntity> nodesList = GetShopNodeList();
			return NodeTreeItems(nodesList);
		}

		/// <summary> 
		/// 生成节点下拉选择树  ├ └
		/// </summary>
		/// <param name="nodeList"></param>
		/// <returns></returns>
		private IList<NodesEntity> NodeTreeItems(IList<NodesEntity> nodeList)
		{
			int index = 0;
			char ch = '\x00a0';
			bool[] flagArray = new bool[50];
			foreach (NodesEntity info in nodeList)
			{
				index = (int)info.Depth;
				if (info.NextID > 0)
				{
					flagArray[index] = true;
				}
				else
				{
					flagArray[index] = false;
				}
				StringBuilder builder = new StringBuilder();
				if (index > 0)
				{
					for (int i = 1; i <= index; i++)
					{
						builder.Append(ch);
						builder.Append(ch);
						if (i == index)
						{
							if (info.NextID > 0)
							{
								builder.Append("├");
								builder.Append(ch);
							}
							else
							{
								builder.Append("└");
								builder.Append(ch);
							}
						}
						else if (flagArray[i])
						{
							builder.Append("│");
						}
						else
						{
							builder.Append(ch);
						}
					}
				}
				builder.Append(info.NodeName);
				if (info.NodeType == (int)(NodeType.Link))
				{
					builder.Append("(外)");
				}
				info.NodeName = builder.ToString();
			}
			return nodeList;
		}
		#endregion

		#region 是否存在数据
		/// <summary>
		///  判断同级节点下是否存在同名的节点目录
		/// </summary>
		/// <param name="parentId">父节点ID</param>
		/// <param name="nodeDir">目录名称</param>
		/// <returns></returns>
		public bool ExistsNodeDir(int parentId, string nodeDir)
		{
			if (string.IsNullOrEmpty(nodeDir))
			{
				return false;
			}
			return IsExist(p => p.ParentID == parentId && p.NodeDir == nodeDir);
		}
		/// <summary>
		///  判断同级节点下是否存在同名的节点标识
		/// </summary>
		/// <param name="parentId">父节点ID</param>
		/// <param name="nodeIdentifier">节点标识</param>
		/// <returns></returns>
		public bool ExistsNodeIdentifier(int parentId, string nodeIdentifier)
		{
			if (string.IsNullOrEmpty(nodeIdentifier))
			{
				return false;
			}
			return IsExist(p => p.ParentID == parentId && p.NodeIdentifier == nodeIdentifier);
		}
		/// <summary>
		///  判断同级节点下是否存在同名的节点名称
		/// </summary>
		/// <param name="parentId">父节点ID</param>
		/// <param name="nodeName">节点名称</param>
		/// <returns></returns>
		public bool ExistsNodeName(int parentId, string nodeName)
		{
			if (string.IsNullOrEmpty(nodeName))
			{
				return false;
			}
			return IsExist(p => p.ParentID == parentId && p.NodeName == nodeName);
		}
		/// <summary>
		/// 判断移动的节点是否包含目标节点
		/// </summary>
		/// <param name="targetNodeId">目标节点</param>
		/// <param name="arrChildId">子节点ID，多个ID用“,”分割</param>
		/// <returns></returns>
		public bool ExistsTargetNodeIdInArrChildId(int targetNodeId, string arrChildId)
		{
			if (!DataValidator.IsValidId(arrChildId))
			{
				return false;
			}
			Expression<Func<NodesEntity, bool>> predicate = p => p.NodeID == targetNodeId;
			var arrNodeID = arrChildId.Split(',');
			predicate = predicate.And(p => arrNodeID.Contains(p.NodeID.ToString()));
			return IsExist(predicate);
		}
		#endregion

		#region 判断数据是否正确
		/// <summary>
		/// 判断指定的模板ID，是否为指定节点的默认模板ID
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public bool GetDefaultTemplate(int nodeId, int templateId)
		{
			return _NodesTemplateRepository.Get(p => p.NodeID == nodeId && p.TemplateID == templateId).IsDefault;
		}
		#endregion

		#region 检查节点权限
		/// <summary>
		/// 检查节点权限
		/// 1、节点是否存在。
		/// 2、有子栏目时是否可以在此栏目添加内容
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public bool CheckNodePermission(int nodeId)
		{
			if (nodeId > 0)
			{
				var cacheNodeById = GetCacheNodeById(nodeId);
				if (cacheNodeById == null)
				{
					return false;
				}
				if (cacheNodeById.SettingsInfo.IsNull)
				{
					return false;
				}
				if (!cacheNodeById.SettingsInfo.EnableAddWhenHasChild && (cacheNodeById.Child > 0))
				{
					return false;
				}
			}
			return true;
		}
		/// <summary>
		/// 检查当前登录管理员，对指定节点，指定操作，是否有权限
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="operateCode"></param>
		/// <returns></returns>
		public bool CheckRoleNodePurview(int nodeId, OperateCode operateCode)
		{
			bool flag = true;
			if (MyHttpContext.IsSuperAdmin)
			{
				return flag;
			}
			if (nodeId > 0)
			{
				var cacheNodeById = GetCacheNodeById(nodeId);
				flag = _RolesServiceApp.AccessCheckNodePermission(operateCode, cacheNodeById.NodeID.ToInt32());
				if (!flag && (cacheNodeById.ParentID > 0))
				{
					string roleNodeId = _RolesServiceApp.GetRoleNodeId(MyHttpContext.CurrentRoleID, operateCode);
					string findStr = cacheNodeById.ParentPath + "," + cacheNodeById.NodeID.ToString();
					flag = StringHelper.FoundCharInArr(roleNodeId, findStr);
				}
				return flag;
			}
			return false;
		}
		#endregion

		#region 检查IP
		/// <summary>
		/// 检查当前登录用户的IP是否在指定的IP白名单中，只对动态页面有效。
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <returns></returns>
		public bool CheckIPlock(NodesEntity nodeInfo)
		{
			bool analysisResult = false;
			if (!nodeInfo.IsCreateContentPage && !nodeInfo.IsCreateListPage)
			{
				if (nodeInfo.IPLockInfo.IsOpeningLockIP)
				{
					double userIP = IPHelper.EncodeIP(Utility.GetClientIP());
					if (string.IsNullOrEmpty(nodeInfo.IPLockInfo.LockIPWhite))
					{
						string lockIPWhite = ConfigHelper.Get<IPLockConfig>().LockIPWhite;
						if (!string.IsNullOrEmpty(lockIPWhite))
						{
							analysisResult = GetAnalysisResult(lockIPWhite, userIP);
						}
						return analysisResult;
					}
					return GetAnalysisResult(nodeInfo.IPLockInfo.LockIPWhite, userIP);
				}
				return true;
			}
			return true;
		}
		/// <summary>
		/// 检查指定IP是否在指定的IP列表中
		/// </summary>
		/// <param name="lockList"></param>
		/// <param name="userIP"></param>
		/// <returns></returns>
		private bool GetAnalysisResult(string lockList, double userIP)
		{
			bool flag = false;
			if (!string.IsNullOrEmpty(lockList))
			{
				string[] strArray = lockList.Split(new string[] { "$$$" }, StringSplitOptions.RemoveEmptyEntries);
				for (int i = 0; i < strArray.Length; i++)
				{
					if (!string.IsNullOrEmpty(strArray[i]))
					{
						try
						{
							string[] strArray2 = strArray[i].Split(new string[] { "----" }, StringSplitOptions.RemoveEmptyEntries);
							double startIP = IPHelper.EncodeIP(strArray2[0]);
							double endIP = IPHelper.EncodeIP(strArray2[1]);
							flag = (startIP <= userIP) && (userIP <= endIP);
						}
						catch (IndexOutOfRangeException)
						{
							return false;
						}
					}
				}
			}
			return flag;
		}
		#endregion

		#region 添加、修改、删除节点

		#region 添加节点
		/// <summary>
		/// 添加节点。
		/// 1.生成新节点ID。
		/// 2.检查节点名称和节点标识符是否已存在。
		/// 3.如果节点为容器节点，则判断节点目录是否存在。
		/// 4.如果节点不是根节点则检查父节点是否存在 ,并检查父节点是否为链接节点或单页节点。
		/// 5.更新父节点的子节点信息。
		/// 6.生成前一节点后一节点ID,更新前一节点后一节点的信息。
		/// 7.清除缓存节点。
		/// 8.返回值：0:添加失败；1:添加成功；2:节点名存在；3:节点标识符存在；4:节点目录存在；5:父节点为链接节点或单页节点不允许添加；6:父节点不存在
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <returns></returns>
		public int AddNode(NodesEntity nodeInfo)
		{
			int maxRootId = GetMaxRootId();
			nodeInfo.NodeID = GetMaxNodeId() + 1;
			nodeInfo.ArrChildID = nodeInfo.NodeID.ToString();
			nodeInfo.Child = 0;
			if (ExistsNodeName(nodeInfo.ParentID.ToInt32(), nodeInfo.NodeName))
			{
				return 2;
			}
			if (ExistsNodeIdentifier(nodeInfo.ParentID.ToInt32(), nodeInfo.NodeIdentifier))
			{
				return 3;
			}
			if (nodeInfo.NodeType < (int)NodeType.Special)
			{
				nodeInfo.ParentDir = "/" + nodeInfo.ParentDir;
				if (ExistsNodeDir(nodeInfo.ParentID.ToInt32(), nodeInfo.NodeDir))
				{
					return 4;
				}
			}
			if (nodeInfo.ParentID > 0)
			{
				NodesEntity cacheNodeById = GetCacheNodeById(nodeInfo.ParentID.ToInt32());
				if (cacheNodeById==null)
				{
					return 6;
				}
				nodeInfo.ParentPath = cacheNodeById.ParentPath + "," + cacheNodeById.NodeID.ToString();
				nodeInfo.RootID = cacheNodeById.RootID;
				nodeInfo.Depth = cacheNodeById.Depth + 1;
				nodeInfo.ParentDir = cacheNodeById.ParentDir + cacheNodeById.NodeDir + "/";
				if ((cacheNodeById.NodeType == (int)NodeType.Single) || (cacheNodeById.NodeType == (int)NodeType.Link))
				{
					return 5;
				}
				UpdateChild(nodeInfo.ParentID.ToInt32());
				foreach (KeyValuePair<int, string> pair in GetParentPathArrChildId(nodeInfo.ParentPath))
				{
					int key = pair.Key;
					string arrChildId = pair.Value + "," + nodeInfo.NodeID.ToString();
					UpdateArrChildId(key, arrChildId);
				}
				if (cacheNodeById.Child > 0)
				{
					nodeInfo.OrderSort = GetPrevOrderId(cacheNodeById.ArrChildID);
					nodeInfo.PrevID = GetPrevId(nodeInfo.ParentID.ToInt32());
				}
				else
				{
					nodeInfo.OrderSort = cacheNodeById.OrderSort;
					nodeInfo.PrevID = 0;
				}
			}
			else
			{
				nodeInfo.ParentDir = "/";
				if (maxRootId > 0)
				{
					nodeInfo.PrevID = GetRootPrevId(maxRootId);
				}
				else
				{
					nodeInfo.PrevID = 0;
				}
				nodeInfo.RootID = maxRootId + 1;
				nodeInfo.ParentPath = "0";
				nodeInfo.OrderSort = 0;
				nodeInfo.Depth = 0;
			}
			UpdateNextId(nodeInfo.PrevID.ToInt32(), nodeInfo.NodeID.ToInt32());
			bool flag = Add(nodeInfo);
			UpdateOrderId(nodeInfo.RootID.ToInt32(), nodeInfo.OrderSort.ToInt32(), 1);
			if (nodeInfo.ParentID > 0)
			{
				UpdateOrderId(nodeInfo.NodeID.ToInt32(), nodeInfo.OrderSort.ToInt32() + 1);
			}
			RemoveCacheAllNodeInfo();
			if (!flag)
			{
				return 0;
			}
			return 1;
		}
		/// <summary>
		/// 1、添加节点并添加节点模型模板。
		/// 2、生成节点静态化所用的文件夹。
		/// 3、生成AjaxProxyPage页面。
		/// 4、返回值：0:添加失败；1:添加成功；2:节点名存在；3:节点标识符存在；4:节点目录存在；5:父节点为链接节点或单页节点不允许添加；6:父节点不存在
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <param name="infoList"></param>
		/// <returns></returns>
		public int AddNode(NodesEntity nodeInfo, IList<NodesModelTemplateEntity> infoList)
		{
			int num = AddNode(nodeInfo);
			if (num == 1)
			{
				CreateAndNodeDir(nodeInfo);
				foreach (var info in infoList)
				{
					info.NodeID = nodeInfo.NodeID;
					if (!_ModelsServiceApp.ExistsNodesModelTemplateRelationShip(info))
					{
						_ModelsServiceApp.AddNodesModelTemplateRelationShip(info);
					}
				}
			}
			return num;
		}
		#endregion

		#region 更新节点
		/// <summary>
		/// 更新节点。
		/// 1、判断节点名称和节点标识符是否存在。
		/// 2、更新节点。
		/// 3、生成节点静态化所用的文件夹。
		/// 4、生成AjaxProxyPage页面。
		/// 5、删除所有节点缓存。
		/// 6、返回值：0：更新失败；1：更新成功；2：节点名称已经存在；3：节点标识符已经存在；
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <returns></returns>
		public int UpdateNode(NodesEntity nodeInfo)
		{
			NodesEntity cacheNodeById = GetCacheNodeById(nodeInfo.NodeID.ToInt32());
			if ((nodeInfo.NodeName != cacheNodeById.NodeName) && ExistsNodeName(nodeInfo.ParentID.ToInt32(), nodeInfo.NodeName))
			{
				return 2;
			}
			if ((nodeInfo.NodeIdentifier != cacheNodeById.NodeIdentifier) && ExistsNodeIdentifier(nodeInfo.ParentID.ToInt32(), nodeInfo.NodeIdentifier))
			{
				return 3;
			}
			if (Update(nodeInfo))
			{
				CreateAndNodeDir(nodeInfo);
				RemoveCacheByNodeId(nodeInfo.NodeID.ToInt32());
				return 1;
			}
			return 0;
		}
		/// <summary>
		/// 更新节点及节点模板。
		/// 1、判断节点名称和节点标识符是否存在。
		/// 2、更新节点。
		/// 3、生成节点静态化所用的文件夹。
		/// 4、生成AjaxProxyPage页面。
		/// 5、删除所有节点缓存。
		/// 6、更新节点模型模板关系。
		/// 7、返回值：0：更新失败；1：更新成功；2：节点名称已经存在；3：节点标识符已经存在；
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <param name="infoList"></param>
		/// <returns></returns>
		public int UpdateNode(NodesEntity nodeInfo, IList<NodesModelTemplateEntity> infoList)
		{
			int num = UpdateNode(nodeInfo);
			if (num == 1)
			{
				_ModelsServiceApp.UpdateNodesModelTemplateRelationShip(nodeInfo.NodeID.ToInt32(), infoList);
			}
			return num;
		}
		#endregion

		#region 删除节点、节点目录及相关联系
		/// <summary>
		/// 删除节点。
		/// 1.删除文件夹。
		/// 2.删除所有节点关系。
		/// 3.删除节点下的所有内容信息。
		/// 4.删除所有子节点。
		/// 5.更新父节点。
		/// 6.修复节点目录关系。
		/// 7.清除缓存节点。
		/// 8.返回值：1：删除成功；2：节点不存在；3：首页节点，禁止删除；4：删除节点目录失败；
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public int Delete(int nodeId)
		{
			if (nodeId == 0)
			{
				return 3;
			}
			NodesEntity cacheNodeById = GetCacheNodeById(nodeId);
			if (cacheNodeById==null)
			{
				return 2;
			}
			try
			{
				DeleteNodeFolder(cacheNodeById);
			}
			catch
			{
				return 4;
			}
			DeleteNodeRelationByNodeId(nodeId);
			//ContentManage.DeleteByNodeId(cacheNodeById.ArrChildID, -4);
			DeleteInArrChild(cacheNodeById.ArrChildID);
			if (cacheNodeById.ParentID > 0)
			{
				NodesEntity nodeInfo = GetCacheNodeById(cacheNodeById.ParentID.ToInt32());
				nodeInfo.Child--;
				nodeInfo.ArrChildID = nodeInfo.ArrChildID.Replace("," + cacheNodeById.ArrChildID, string.Empty);
				Update(nodeInfo);
			}
			PatchNodes();
			RemoveCacheAllNodeInfo();
			return 1;
		}
		/// <summary>
		/// 删除所有指定的节点
		/// </summary>
		/// <param name="arrChildId">节点ID，多个ID用“,”分割</param>
		/// <returns></returns>
		public bool DeleteInArrChild(string arrChildId)
		{
			if (!DataValidator.IsValidId(arrChildId))
			{
				return false;
			}
			RemoveCacheAllNodeInfo();
			var arrID = StringHelper.GetArrayBySplit<int?>(arrChildId).ToArray();
			return m_repository.Delete(p=>p.NodeID.In(arrID));
		}
		/// <summary>
		/// 删除节点对应的目录
		/// </summary>
		/// <param name="nodeInfo"></param>
		private void DeleteNodeFolder(NodesEntity nodeInfo)
		{
			if (!string.IsNullOrEmpty(nodeInfo.ParentDir) && !string.IsNullOrEmpty(nodeInfo.NodeDir))
			{
				string path = "~/" + ConfigHelper.Get<SiteOptionConfig>().CreateHtmlPath + nodeInfo.ParentDir + nodeInfo.NodeDir;
				FileHelper.Delete(FileHelper.MapPath(path), FileMethod.Folder);
			}
		}
		/// <summary>
		/// 删除节点与角色(RolePermissions)、会员(UserPermissions)、模型模板(NodesModelTemplate)的所有关系
		/// </summary>
		/// <param name="nodeId"></param>
		private void DeleteNodeRelationByNodeId(int nodeId)
		{
			_RolesServiceApp.DeleteNodePermissionFromRoles(-1, nodeId);
			_UserGroupsServiceApp.DeleteNodePermissionFromGroup(0,nodeId, OperateCode.None,-1);
			_ModelsServiceApp.DeleteNodesModelTemplateRelationShip(nodeId);
		}
		#endregion

		/// <summary>
		/// 创建节点对应的静态化文件保存目录
		/// </summary>
		/// <param name="nodeInfo"></param>
		private void CreateAndNodeDir(NodesEntity nodeInfo)
		{
			if (((nodeInfo.ParentID == 0) && nodeInfo.IsSubDomain) && (nodeInfo.IsCreateListPage && (nodeInfo.NodeType == (int)(NodeType.Container))))
			{
				FileHelper.CreateFileFolder(ConfigHelper.Get<SiteOptionConfig>().CreateHtmlPath + Utility.AppendTrailingSlash(nodeInfo.NodeDir));
			}
		}
		#endregion

		#region 批量更新节点的“栏目选项”与“前台样式”等属性设置
		/// <summary>
		/// 批量更新节点的“栏目选项”与“前台样式”。
		/// 批量更新节点指定字段列表（包括节点设置字段nodeInfo.Settings（EnableComment，EnableProtect，EnableValidCode，EnableAddWhenHasChild，PresentExp,ShowChargeType,DefaultItemPoint,DefaultItemDividePercent）)
		/// </summary>
		/// <param name="nodeInfo">包含新节点值的节点对象</param>
		/// <param name="nodesId">要批量更新的节点集，多个ID用“,”分割</param>
		/// <param name="checkItem">指定要更新的字段列表：checkItem["EnableComment"]=true </param>
		/// <returns></returns>
		public bool BatchUpdate(NodesEntity nodeInfo, string nodesId, Dictionary<string, bool> checkItem)
		{
			foreach (var info in GetNodeList(nodesId))
			{
				NodeSettingInfo settings = info.SettingsInfo;
				if (checkItem["EnableComment"])
				{
					settings.EnableComment = nodeInfo.SettingsInfo.EnableComment;
					settings.CommentNeedCheck = nodeInfo.SettingsInfo.CommentNeedCheck;
					settings.EnableTouristsComment = nodeInfo.SettingsInfo.EnableTouristsComment;
				}
				if (checkItem["EnableProtect"])
				{
					settings.EnableProtect = nodeInfo.SettingsInfo.EnableProtect;
				}
				if (checkItem["EnableValidCode"])
				{
					settings.EnableValidCode = nodeInfo.SettingsInfo.EnableValidCode;
				}
				if (checkItem["EnableAddWhenHasChild"])
				{
					settings.EnableAddWhenHasChild = nodeInfo.SettingsInfo.EnableAddWhenHasChild;
				}
				if (checkItem["PresentExp"])
				{
					settings.PresentExp = nodeInfo.SettingsInfo.PresentExp;
				}
				if (checkItem["DefaultItemPoint"])
				{
					settings.DefaultItemPoint = nodeInfo.SettingsInfo.DefaultItemPoint;
				}
				if (checkItem["ShowChargeType"])
				{
					settings.DefaultItemChargeType = nodeInfo.SettingsInfo.DefaultItemChargeType;
					settings.DefaultItemPitchTime = nodeInfo.SettingsInfo.DefaultItemPitchTime;
					settings.DefaultItemReadTimes = nodeInfo.SettingsInfo.DefaultItemReadTimes;
				}
				if (checkItem["DefaultItemDividePercent"])
				{
					settings.DefaultItemDividePercent = nodeInfo.SettingsInfo.DefaultItemDividePercent;
				}
				m_repository.Update("Settings = @Settings", " and NodeID=@NodeID", new { Settings = settings.ToXml(), info.NodeID });
			}
			BatchUpdateField(nodeInfo, nodesId, checkItem);
			RemoveCacheAllNodeInfo();
			return true;
		}
		/// <summary>
		/// 批量更新节点的“前台样式”。
		/// 批量更新节点字段 OpenType PurviewType WorkFlowID HitsOfHot LeastOfEliteLevel ShowOnMenu ShowOnListIndex
		/// </summary>
		/// <param name="nodeInfo">包含新节点值的节点对象</param>
		/// <param name="nodesId">要批量更新的节点集，多个ID用“,”分割</param>
		/// <param name="checkItem">指定要更新的字段列表</param>
		/// <returns></returns>
		public bool BatchUpdateField(NodesEntity nodeInfo, string nodesId, Dictionary<string, bool> checkItem)
		{
			if (!DataValidator.IsValidId(nodesId))
			{
				return false;
			}
			if (!checkItem.ContainsValue(true))
			{
				return false;
			}
			StringBuilder builder = new StringBuilder();
			if (checkItem["OpenType"])
			{
				builder.Append("OpenType = @OpenType,");
			}
			if (checkItem["PurviewType"])
			{
				builder.Append("PurviewType = @PurviewType,");
			}
			if (checkItem["WorkFlowID"])
			{
				builder.Append("WorkFlowID = @WorkFlowID,");
			}
			if (checkItem["HitsOfHot"])
			{
				builder.Append("HitsOfHot = @HitsOfHot,");
			}
			if (checkItem["LeastOfEliteLevel"])
			{
				builder.Append("LeastOfEliteLevel = @LeastOfEliteLevel,");
			}
			if (checkItem["FileCdefaultListTmeplate"])
			{
				builder.Append("DefaultTemplateFile = @DefaultTemplateFile,");
			}
			if (checkItem["FileContainChildTemplate"])
			{
				builder.Append("ContainChildTemplateFile = @ContainChildTemplateFile,");
			}
			if (checkItem["IsShowOnMenu"])
			{
				builder.Append("IsShowOnMenu = @IsShowOnMenu,");
			}
			if (checkItem["IsShowOnPath"])
			{
				builder.Append("IsShowOnPath = @IsShowOnPath,");
			}
			if (checkItem["IsShowOnMap"])
			{
				builder.Append("IsShowOnMap = @IsShowOnMap,");
			}
			if (checkItem["IsShowOnList_Index"])
			{
				builder.Append("IsShowOnList_Index = @IsShowOnList_Index,");
			}
			if (checkItem["IsShowOnList_Parent"])
			{
				builder.Append("IsShowOnList_Parent = @IsShowOnList_Parent,");
			}
			if (checkItem["ItemPageSize"])
			{
				builder.Append("ItemPageSize = @ItemPageSize,");
			}
			if (checkItem["ItemOpenType"])
			{
				builder.Append("ItemOpenType = @ItemOpenType,");
			}
			if (checkItem["ItemListOrderType"])
			{
				builder.Append("ItemListOrderType = @ItemListOrderType,");
			}
			if (checkItem["ListPageCreateHtmlType"])
			{
				builder.Append("IsCreateListPage = @IsCreateListPage,");
			}
			if (checkItem["AutoCreateHtmlType"])
			{
				builder.Append("AutoCreateHtmlType = @AutoCreateHtmlType,");
			}
			if (checkItem["Relation"])
			{
				builder.Append("RelateSpecial = @RelateSpecial,");
				builder.Append("RelateNode = @RelateNode,");
			}
			if (checkItem["ListPageHtmlDirType"])
			{
				builder.Append("ListPageSavePathType = @ListPageSavePathType,");
			}
			if (checkItem["PagePostfix"])
			{
				builder.Append("ListPagePostFix = @ListPagePostFix,");
			}
			if (checkItem["ContentPageCreateHtmlType"])
			{
				builder.Append("IsCreateContentPage = @IsCreateContentPage,");
			}
			if (checkItem["ContentHtmlDir"])
			{
				builder.Append("ContentPageHtmlRule = @ContentPageHtmlRule,");
			}
			if (builder.Length <= 0)
			{
				return true;
			}
			builder.Remove(builder.Length - 1, 1);
			return m_repository.Update(builder.ToString(), " and NodeID in @ids", new
			{
				ids = StringHelper.GetArrayBySplit<int>(nodesId).ToArray(),
				nodeInfo.OpenType,
				nodeInfo.PurviewType,
				nodeInfo.WorkFlowID,
				nodeInfo.HitsOfHot,
				nodeInfo.LeastOfEliteLevel,
				nodeInfo.DefaultTemplateFile,
				nodeInfo.ContainChildTemplateFile,
				nodeInfo.IsShowOnMenu,
				nodeInfo.IsShowOnPath,
				nodeInfo.IsShowOnMap,
				nodeInfo.IsShowOnList_Index,
				nodeInfo.IsShowOnList_Parent,
				nodeInfo.ItemPageSize,
				nodeInfo.ItemOpenType,
				nodeInfo.ItemListOrderType,
				nodeInfo.IsCreateListPage,
				nodeInfo.AutoCreateHtmlType,
				nodeInfo.RelateSpecial,
				nodeInfo.RelateNode,
				nodeInfo.ListPageSavePathType,
				nodeInfo.ListPagePostFix,
				nodeInfo.IsCreateContentPage,
				nodeInfo.ContentPageHtmlRule
			});
		}
		#endregion

		#region 更新和得到节点排序号
		/// <summary>
		/// 更新节点排序号
		/// </summary>
		/// <param name="nodeId">节点ID</param>
		/// <param name="orderId">排序号</param>
		/// <returns></returns>
		public bool UpdateOrderId(int nodeId, int orderId)
		{
			RemoveCacheByNodeId(nodeId);
			return m_repository.Update("OrderSort=@OrderSort", " and NodeID=@NodeID",new { OrderSort = orderId, NodeID= nodeId });
		}
		/// <summary>
		/// 更新节点排序号：更新指定根节点下的所有排序号，条件为当前排序号大于指定排序号的节点
		/// </summary>
		/// <param name="rootId">根节点ID</param>
		/// <param name="orderId">排序号</param>
		/// <param name="addNum">在当前排序号上，要添加的排序数量</param>
		/// <returns></returns>
		public bool UpdateOrderId(int rootId, int orderId, int addNum)
		{
			RemoveCacheAllNodeInfo();
			return m_repository.Update("OrderSort = OrderSort + @AddNum", " and RootID = @RootId AND OrderSort > @OrderSort", new { AddNum = addNum, RootId = rootId, OrderSort= orderId });
		}
		/// <summary>
		/// 获取指定节点集中的最大排序号
		/// </summary>
		/// <param name="arrChildId">节点ID，多个ID用“,”分割</param>
		/// <returns></returns>
		public int GetPrevOrderId(string arrChildId)
		{
			if (DataValidator.IsValidId(arrChildId))
			{
				return m_repository.GetScalar<int>("MAX(OrderSort)", " and NodeID in @ids", new { ids = StringHelper.GetArrayBySplit<int>(arrChildId).ToArray() });
			}
			return 0;
		}
		#endregion

		#region 更新和得到节点的栏目权限设置
		/// <summary>
		/// 更新指定节点及所有子节点的栏目权限设置(栏目权限。0--开放栏目  1--半开放栏目  2--认证栏目 3--归档栏目)
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="purviewType">栏目权限。0--开放栏目  1--半开放栏目  2--认证栏目 3--归档栏目</param>
		/// <returns></returns>
		public bool UpdateChildPurview(int nodeId, int purviewType)
		{
			bool flag = true;
			var cacheNodeById = GetCacheNodeById(nodeId);
			if (!DataValidator.IsValidId(cacheNodeById.ArrChildID))
			{
				return false;
			}
			if ((purviewType > 0) || (purviewType < 4))
			{
				flag = m_repository.Update("PurviewType = @PurviewType", " and PurviewType <= @PurviewType AND NodeID IN @ids", new { PurviewType= purviewType, ids = StringHelper.GetArrayBySplit<int>(cacheNodeById.ArrChildID).ToArray() });
			}
			RemoveCacheAllNodeInfo();
			return flag;
		}
		/// <summary>
		/// 更新指定节点的栏目权限设置，与当前节点及所有子节点的栏目权限设置中最严格的设置为同一设置。
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public bool UpdateNodePurviewType(int nodeId)
		{
			bool flag = true;
			var cacheNodeById = GetCacheNodeById(nodeId);
			int maxPurviewTypeInParentPath = GetMaxPurviewTypeInParentPath(nodeId);
			if (cacheNodeById.PurviewType < maxPurviewTypeInParentPath)
			{
				flag = m_repository.Update("PurviewType = @PurviewType", " AND NodeID =@NodeID", new { PurviewType = maxPurviewTypeInParentPath, NodeID = nodeId });
			}
			RemoveCacheAllNodeInfo();
			return flag;
		}
		/// <summary>
		/// 获取指定节点及所有子节点中栏目权限设置最严格的权限类型
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public int GetMaxPurviewTypeInParentPath(int nodeId)
		{
			var cacheNodeById = GetCacheNodeById(nodeId);
			if (!DataValidator.IsValidId(cacheNodeById.ParentPath))
			{
				return 0;
			}
			return m_repository.GetScalar<int>("MAX(PurviewType)", " and NodeID in @ids", new { ids = StringHelper.GetArrayBySplit<int>(cacheNodeById.ParentPath).ToArray() });
		}
		#endregion

		#region 更新节点的子节点数量
		/// <summary>
		/// 更新指定节点的子节点数量（Child = Child + 1）
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public bool UpdateChild(int nodeId)
		{
			RemoveCacheAllNodeInfo();
			return m_repository.Update("Child = Child + 1", "NodeID = @NodeID",new { NodeID= nodeId });
		}
		/// <summary>
		/// 更新指定节点的子节点数量（Child = @Child）
		/// </summary>
		/// <param name="nodeId">节点ID</param>
		/// <param name="child">指定的子节点数量</param>
		/// <returns></returns>
		public bool UpdateChild(int nodeId, int child)
		{
			RemoveCacheAllNodeInfo();
			return m_repository.Update("Child = @Child", "NodeID = @NodeID", new { NodeID = nodeId, Child= child });
		}
		#endregion

		#region 更新IsNeedCreateHtml和ArrChildId属性
		/// <summary>
		/// 更新指定节点的IsNeedCreateHtml属性（是否需要生成静态化HTML）
		/// </summary>
		/// <param name="arrNodeId">节点ID，多个ID用“,”分割</param>
		/// <param name="needCreateHtml">是否需要生成静态化</param>
		/// <returns></returns>
		public bool UpdateNeedCreateHtml(string arrNodeId, bool needCreateHtml)
		{
			if (!DataValidator.IsValidId(arrNodeId))
			{
				return false;
			}
			if (m_repository.Update("IsNeedCreateHtml = @IsNeedCreateHtml", " and NodeID in @ids",new { IsNeedCreateHtml= needCreateHtml, ids = StringHelper.GetArrayBySplit<int>(arrNodeId).ToArray() }))
			{
				RemoveCacheAllNodeInfo();
				return true;
			}
			return false;
		}
		/// <summary>
		/// 更新指定节点的子节点集
		/// </summary>
		/// <param name="nodeId">要更新的节点ID</param>
		/// <param name="arrChildId">子节点集(节点ID，多个ID用“,”分割)</param>
		/// <returns></returns>
		public bool UpdateArrChildId(int nodeId, string arrChildId)
		{
			RemoveCacheAllNodeInfo();
			return m_repository.Update("ArrChildID = @ArrChildID", " and NodeID = @NodeID", new { ArrChildID = arrChildId, NodeID = nodeId });
		}
		#endregion

		#region 排序节点与修复节点结构
		/// <summary>
		/// 重新排序节点
		/// </summary>
		/// <param name="nodeList"></param>
		public void OrderNode(IList<NodesEntity> nodeList)
		{
			var list = (List<NodesEntity>)nodeList;
			list.Sort();
			int count = list.Count;
			for (int i = 0; i < count; i++)
			{
				NodesEntity nodeInfo = list[i];
				if (i == 0)
				{
					nodeInfo.PrevID = 0;
				}
				else
				{
					nodeInfo.PrevID = list[i - 1].NodeID;
				}
				if (i == (count - 1))
				{
					nodeInfo.NextID = 0;
				}
				else
				{
					nodeInfo.NextID = list[i + 1].NodeID;
				}
				if (nodeInfo.OrderSort == 1)
				{
					UpdateRootId(nodeInfo.ArrChildID, nodeInfo.RootID.ToInt32());
				}
				Update(nodeInfo);
			}
			PatchNodes();
		}
		/// <summary>
		/// 修复节点结构
		/// </summary>
		public void PatchNodes()
		{
			IList<NodesEntity> nodesListByParentId = GetNodesListByParentId(0);
			rootId = 0;
			foreach (NodesEntity info in nodesListByParentId)
			{
				ModifyNodeStructure(info);
			}
			RemoveCacheAllNodeInfo();
		}
		#endregion

		#region 更新节点树结构
		/// <summary>
		/// 更新节点树结构
		/// </summary>
		/// <param name="nodeInfo"></param>
		public void ModifyNodeStructure(NodesEntity nodeInfo)
		{
			nodeInfo = GetRootNodeInfo(nodeInfo);
			if (nodeInfo.ParentID == 0)
			{
				orderId = 0;
				UpateNodeStructure(nodeInfo.NodeID.ToInt32(), nodeInfo.Depth.ToInt32() + 1, nodeInfo.ParentPath, "/" + nodeInfo.NodeDir + "/");
			}
			RemoveCacheAllNodeInfo();
		}
		/// <summary>
		/// 删除或者更新节点时更新节点树结构
		/// </summary>
		/// <param name="parentId"></param>
		/// <param name="depth"></param>
		/// <param name="parentPath"></param>
		/// <param name="parentDir"></param>
		private void UpateNodeStructure(int parentId, int depth, string parentPath, string parentDir)
		{
			if (string.IsNullOrEmpty(parentPath))
			{
				parentPath = parentId.ToString();
			}
			else
			{
				parentPath = parentPath + "," + parentId.ToString();
			}
			IList<NodesEntity> nodesListByParentId = GetNodesListByParentId(parentId);
			NodesEntity cacheNodeById = GetCacheNodeById(parentId);
			cacheNodeById.Child = nodesListByParentId.Count;
			cacheNodeById.OrderSort = orderId;
			cacheNodeById.ArrChildID = parentId.ToString();
			if (cacheNodeById.ParentID == 0)
			{
				rootId++;
				cacheNodeById.RootID = rootId;
				cacheNodeById.Depth = 0;
			}
			Update(cacheNodeById);
			int num = 0;
			foreach (NodesEntity info2 in nodesListByParentId)
			{
				orderId++;
				info2.OrderSort = orderId;
				info2.Depth = depth;
				info2.ParentPath = parentPath;
				info2.RootID = cacheNodeById.RootID;
				if (info2.NodeType == (int)(NodeType.Container))
				{
					info2.ParentDir = parentDir;
				}
				if (num == 0)
				{
					info2.PrevID = 0;
				}
				else
				{
					info2.PrevID = nodesListByParentId[num - 1].NodeID;
				}
				if (num == (nodesListByParentId.Count - 1))
				{
					info2.NextID = 0;
				}
				else
				{
					info2.NextID = nodesListByParentId[num + 1].NodeID;
				}
				info2.ArrChildID = info2.NodeID.ToString();
				Update(info2);
				string str = (Utility.AppendTrailingSlash(info2.ParentDir) + info2.NodeDir + "/").Replace("//", "/");
				UpateNodeStructure(info2.NodeID.ToInt32(), info2.Depth.ToInt32() + 1, info2.ParentPath, str);
				num++;
			}
			UpdateArrChildStructure(nodesListByParentId);
		}
		/// <summary>
		/// 更新子节点树结构
		/// </summary>
		/// <param name="nodeList"></param>
		private void UpdateArrChildStructure(IList<NodesEntity> nodeList)
		{
			foreach (NodesEntity info in nodeList)
			{
				foreach (NodesEntity info2 in GetNodesListInArrChildId(info.ParentPath))
				{
					info2.ArrChildID = info2.ArrChildID + "," + info.NodeID.ToString();
					UpdateArrChildId(info2.NodeID.ToInt32(), info2.ArrChildID);
				}
			}
		}
		#endregion

		#region 整理节点树
		/// <summary>
		/// 重新整理子节点树。返回值：0：整理成功；1：节点不存在或不是根节点；
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public int ResetChildNodes(int nodeId)
		{
			NodesEntity cacheNodeById = GetCacheNodeById(nodeId);
			if (cacheNodeById == null || (cacheNodeById.ParentID != 0))
			{
				return 1;
			}
			IList<NodesEntity> nodesListInArrChildId = GetNodesListInArrChildId(cacheNodeById.ArrChildID);
			nodesListInArrChildId.Remove(cacheNodeById);
			int num = 0;
			int count = 0;
			count = nodesListInArrChildId.Count;
			foreach (NodesEntity info2 in nodesListInArrChildId)
			{
				if (num == 0)
				{
					info2.PrevID = 0;
				}
				else
				{
					info2.PrevID = nodesListInArrChildId[num - 1].NodeID;
				}
				if (num == (count - 1))
				{
					info2.NextID = 0;
				}
				else
				{
					info2.NextID = nodesListInArrChildId[num + 1].NodeID;
				}
				info2.NodeDir = info2.ParentDir.Replace("/", string.Empty) + info2.NodeDir;
				info2.RootID = cacheNodeById.RootID;
				num++;
				info2.OrderSort = num;
				info2.ParentID = cacheNodeById.NodeID;
				info2.Child = 0;
				info2.ArrChildID = info2.NodeID.ToString();
				info2.ParentPath = "0," + cacheNodeById.NodeID.ToString();
				info2.Depth = cacheNodeById.Depth + 1;
				info2.ParentDir = cacheNodeById.ParentDir + cacheNodeById.NodeDir + info2.NodeDir;
				Update(info2);
			}
			cacheNodeById.Child = count;
			Update(cacheNodeById);
			return 0;
		}
		/// <summary>
		/// 重新整理节点树。所有节点都将作为一级节点
		/// </summary>
		public void ResetNodes()
		{
			int num = 0;
			int count = 0;
			IList<NodesEntity> nodesList = GetNodeList();
			count = nodesList.Count;
			foreach (NodesEntity info in nodesList)
			{
				if (num == 0)
				{
					info.PrevID = 0;
				}
				else
				{
					info.PrevID = nodesList[num - 1].NodeID;
				}
				if (num == (count - 1))
				{
					info.NextID = 0;
				}
				else
				{
					info.NextID = nodesList[num + 1].NodeID;
				}
				info.RootID = num + 1;
				info.OrderSort = 0;
				info.ParentID = 0;
				info.Child = 0;
				info.ArrChildID = info.NodeID.ToString();
				info.ParentPath = "0";
				info.Depth = 0;
				info.ParentDir = "/";
				num++;
				Update(info);
			}
			RemoveCacheAllNodeInfo();
		}
		#endregion

		#region 得到、更新根节点ID
		/// <summary>
		/// 获取最大根节点ID
		/// </summary>
		/// <returns></returns>
		private int GetMaxRootId()
		{
			return m_repository.GetScalar<int>("Max(RootID)");
		}
		/// <summary>
		/// 更新节点的根节点ID
		/// </summary>
		/// <param name="nodeId">节点ID，多个ID用“,”分割</param>
		/// <param name="rootId"></param>
		/// <returns></returns>
		private bool UpdateRootId(string nodeId, int rootId)
		{
			return m_repository.Update("RootID = @RootId", " NodeId IN(" + DataSecurity.ToValidId(nodeId) + ")", new { RootId=rootId });
		}
		#endregion

		#region 得到、更新下一节点ID(NextID字段)
		/// <summary>
		/// 获取下一节点ID
		/// </summary>
		/// <param name="depth">节点深度</param>
		/// <param name="parentPath">节点ID，多个ID用“,”分割</param>
		/// <returns></returns>
		public int GetNextIdByDepth(int depth, string parentPath)
		{
			if (DataValidator.IsValidId(parentPath))
			{
				Expression<Func<NodesEntity, bool>> predicate = p => p.Depth == depth;
				var arrNodeID = parentPath.Split(',');
				predicate = predicate.And(p => arrNodeID.Contains(p.NodeID.ToString()));
				return (int)m_repository.GetScalar(p => p.NextID, predicate);
			}
			return 0;
		}
		/// <summary>
		/// 更新节点的相邻下一个节点ID
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="nextId"></param>
		/// <returns></returns>
		private bool UpdateNextId(int nodeId, int nextId)
		{
			RemoveCacheByNodeId(nodeId);
			return m_repository.Update("NextID=@NextID", "NodeID=@NodeID",new { NextID= nextId , NodeID = nodeId });
		}
		#endregion

		#region 得到最大节点ID、相邻的上一个节点ID、节点审核流程ID
		/// <summary>
		/// 获取节点审核流程ID
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public int GetNodeWorkFlowId(int nodeId)
		{
			var WorkFlowID = m_repository.GetScalar(scalar: p => p.WorkFlowID, predicate: p => p.NodeID == nodeId);
			return WorkFlowID.ToInt32();
		}
		/// <summary>
		/// 获取最大节点ID
		/// </summary>
		/// <returns></returns>
		public int GetMaxNodeId()
		{
			int maxNodeId = m_repository.GetMaxID();
			if (maxNodeId < 0)
			{
				maxNodeId = 0;
			}
			return maxNodeId;
		}
		/// <summary>
		/// 得到相邻的上一个节点ID
		/// </summary>
		/// <param name="parentId">当前节点的父节点ID</param>
		/// <returns></returns>
		public int GetPrevId(int parentId)
		{
			var nodeId = m_repository.GetScalar(scalar: p => p.NodeID, predicate: p => p.ParentID == parentId, orderby: p => p.OrderByDescending(item => item.OrderSort));
			return nodeId.ToInt32();
		}
		/// <summary>
		/// 获取根节点的前一节点ID(条件：RootID = @RootID AND Depth = 0)
		/// </summary>
		/// <param name="maxRootId"></param>
		/// <returns></returns>
		public int GetRootPrevId(int maxRootId)
		{
			var nodeId = m_repository.GetScalar(scalar: p => p.NodeID, predicate: p => p.RootID == maxRootId && p.Depth == 0);
			return nodeId.ToInt32();
		}
		#endregion

		#region 得到、更新节点的语言名称设置
		/// <summary>
		/// 通过信息ID，获取所属节点的语言名称
		/// </summary>
		/// <param name="generalId"></param>
		/// <returns></returns>
		public string GetCultureNameByGeneralId(int generalId)
		{
			var commonModelInfoById = _CommonInfoServiceApp.Get(generalId);
			if (commonModelInfoById != null)
			{
				return GetCacheNodeById(commonModelInfoById.NodeID.ToInt32()).CultureName;
			}
			return string.Empty;
		}
		/// <summary>
		/// 判断节点是否设置了语言区域选项,如果没有则设置为站点配置语言区域选项
		/// </summary>
		public void IsNodesExistCultureName()
		{
			var nodesList = GetNodeList();
			var siteConfigDefaultCulture = "zh-CN";
			foreach (var info in nodesList)
			{
				if ((info.NodeType != (int)NodeType.Container) && (info.NodeType != (int)NodeType.Single))
				{
					continue;
				}
				if (string.IsNullOrEmpty(info.CultureName))
				{
					info.CultureName = siteConfigDefaultCulture;
					Update(info);
				}
			}
		}
		#endregion

		#region 获取总节点数、节点下的内容信息数量、同级目录的节点数量
		/// <summary>
		/// 统计指定节点下的内容信息数量(通过表：CommonInfo)
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public int GetCountModelByNodeId(int nodeId)
		{
			return _CommonInfoServiceApp.GetCount(p => p.NodeID == nodeId);
		}
		/// <summary>
		/// 获取同级目录的节点数量(条件：ParentID=@ParentID AND NodeID《》@NodeID AND NodeDir=@NodeDir)
		/// </summary>
		/// <param name="parentId"></param>
		/// <param name="nodeId"></param>
		/// <param name="nodeDir"></param>
		/// <returns></returns>
		public int GetCountNodesBySameNodeDir(int parentId, int nodeId, string nodeDir)
		{
			return m_repository.GetCount(p => p.ParentID == parentId && p.NodeID != nodeId && p.NodeDir==nodeDir);
		}
		/// <summary>
		/// 获取总节点数
		/// </summary>
		/// <returns></returns>
		public int GetTotalOfNodes()
		{
			return m_repository.GetCount();
		}
		#endregion

		#region 上传路径解析
		/// <summary>
		/// 上传路径解析。
		/// 根据节点及站点配置的生成HTML的文件名规则生成文件名:替换{$FileType} {$Year} {$Month}等为实际值
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <param name="fileName">上传文件名</param>
		/// <returns></returns>
		public string UploadPathParse(NodesEntity nodeInfo, string fileName)
		{
			string uploadFilePathRule = ConfigHelper.Get<UploadFilesConfig>().UploadFilePathRule;
			uploadFilePathRule = ((ResolveUploadDir(nodeInfo, uploadFilePathRule)
				.Replace("{$FileType}", FileHelper.GetFileExtension(fileName).ToLower().Replace(".", string.Empty))
				.Replace("{$Year}", DateTime.Now.Year.ToString())
				.Replace("{$Month}", DateTime.Now.Month.ToString()) + "/")
				.Replace("{$Day}", DateTime.Now.Day.ToString()) + "/")
				.Replace("//", "/");
			return (uploadFilePathRule.StartsWith("/") ? uploadFilePathRule.Substring(1) : uploadFilePathRule);
		}
		/// <summary>
		/// 解析上传目录。
		/// 根据节点上传文件路径规则，生成实际上传路径：替换 {$NodeDir} {$ParentDir} {$NodeIdentifier} {$RootDir}
		/// </summary>
		/// <param name="nodeInfo"></param>
		/// <param name="uploadFilePathRule"></param>
		/// <returns></returns>
		public string ResolveUploadDir(NodesEntity nodeInfo, string uploadFilePathRule)
		{
			uploadFilePathRule = uploadFilePathRule.Replace("{$NodeDir}", nodeInfo.NodeDir);
			uploadFilePathRule = uploadFilePathRule.Replace("{$ParentDir}", nodeInfo.ParentDir.Replace("/", string.Empty));
			uploadFilePathRule = uploadFilePathRule.Replace("{$NodeIdentifier}", nodeInfo.NodeIdentifier);
			if (!string.IsNullOrEmpty(nodeInfo.ParentPath))
			{
				if (nodeInfo.ParentPath.Contains(","))
				{
					string[] strArray = nodeInfo.ParentPath.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
					uploadFilePathRule = uploadFilePathRule.Replace("{$RootDir}", GetCacheNodeById(DataConverter.CLng(strArray[1])).NodeDir);
					return uploadFilePathRule;
				}
				uploadFilePathRule = uploadFilePathRule.Replace("{$RootDir}", nodeInfo.NodeDir);
			}
			return uploadFilePathRule;
		}
		#endregion

		#region 复制、移动、合并节点
		/// <summary>
		/// 拷贝节点及所有关系，成功返回新节点ID。
		/// 返回值：-1：添加“节点－模型－模板”关系失败；0：复制失败；新节点ID：复制成功；
		/// </summary>
		/// <param name="nodeId">被复制的节点ID</param>
		/// <returns></returns>
		public int GetNodeByIdCopyNode(int nodeId)
		{
			int maxNodeId = 0;
			if (nodeId > 0)
			{
				var nodeById = GetNodeById(nodeId);
				nodeById.NodeName = StringHelper.CopyString(nodeById.NodeName);
				nodeById.NodeIdentifier = StringHelper.CopyStringNum(nodeById.NodeIdentifier);
				nodeById.NodeDir = StringHelper.CopyStringNum(nodeById.NodeDir);
				while (ExistsNodeName(nodeById.ParentID.ToInt32(), nodeById.NodeName))
				{
					nodeById.NodeName = StringHelper.CopyString(nodeById.NodeName);
				}
				while (ExistsNodeIdentifier(nodeById.ParentID.ToInt32(), nodeById.NodeIdentifier))
				{
					nodeById.NodeIdentifier = StringHelper.CopyStringNum(nodeById.NodeIdentifier);
				}
				while (ExistsNodeDir(nodeById.ParentID.ToInt32(), nodeById.NodeDir))
				{
					nodeById.NodeDir = StringHelper.CopyStringNum(nodeById.NodeDir);
				}
				if (AddNode(nodeById) != 1)
				{
					return maxNodeId;
				}
				maxNodeId = GetMaxNodeId();
				foreach (var info2 in _ModelsServiceApp.GetNodesModelTemplateList(nodeId))
				{
					info2.NodeID = maxNodeId;
					if (!_ModelsServiceApp.ExistsNodesModelTemplateRelationShip(info2) && !_ModelsServiceApp.AddNodesModelTemplateRelationShip(info2))
					{
						maxNodeId = -1;
					}
				}
				if (MyHttpContext.IsSuperAdmin)
				{
					return maxNodeId;
				}
				//复制角色-节点-权限表数据
				foreach (var info3 in _RolesServiceApp.GetNodePermissionsById(-1, nodeId))
				{
					info3.NodeID = maxNodeId;
					_RolesServiceApp.AddNodePermissionToRoles(info3.RoleID.ToInt32(), info3.NodeID.ToInt32(), (OperateCode)info3.OperateCode.ToInt32());
				}
			}
			return maxNodeId;
		}
		/// <summary>
		/// 移动节点。
		/// 返回值：调用WriteMessageByErrorNum（）方法显示
		/// </summary>
		/// <param name="nodeId">被移动的节点</param>
		/// <param name="moveToNodeId">要移动到的节点</param>
		/// <returns></returns>
		public int NodesMove(int nodeId, int moveToNodeId)
		{
			int num = 0;
			if (nodeId == moveToNodeId)
			{
				return 2;
			}
			var cacheNodeById = GetCacheNodeById(moveToNodeId);
			var nodeInfo = GetCacheNodeById(nodeId);
			if (moveToNodeId > 0)
			{
				num = NodesMoveValidCheck(nodeInfo, cacheNodeById);
				if (num > 0)
				{
					return num;
				}
			}
			nodeInfo.ParentID = moveToNodeId;
			if ((moveToNodeId == 0) || cacheNodeById == null)
			{
				nodeInfo.RootID = GetMaxRootId() + 1;
				nodeInfo.ParentPath = "0";
				nodeInfo.Depth = 0;
				nodeInfo.ParentDir = "/";
				nodeInfo.PrevID = GetMaxNodeId();
				nodeInfo.NextID = 0;
			}
			else
			{
				nodeInfo.ParentPath = cacheNodeById.ParentPath + "," + moveToNodeId.ToString();
				nodeInfo.RootID = cacheNodeById.RootID;
				nodeInfo.Depth = cacheNodeById.Depth + 1;
				nodeInfo.ParentDir = cacheNodeById.ParentDir + cacheNodeById.NodeDir + "/";
				nodeInfo.PrevID = GetPrevId(moveToNodeId);
				nodeInfo.NextID = 0;
			}
			Update(nodeInfo);
			PatchNodes();
			RemoveCacheAllNodeInfo();
			return num;
		}
		/// <summary>
		/// 移动节点前检查目标节点并返回不同的错误状态值:是否同一节点|子节点|不是节点容器。
		/// 返回值：调用WriteMessageByErrorNum（）方法显示
		/// </summary>
		/// <param name="nodeInfo">被移动的节点</param>
		/// <param name="moveToNodeInfo">要移动到的节点</param>
		/// <returns></returns>
		private int NodesMoveValidCheck(NodesEntity nodeInfo, NodesEntity moveToNodeInfo)
		{
			if (nodeInfo==null)
			{
				return 1;
			}
			if (nodeInfo.ParentID == moveToNodeInfo.NodeID)
			{
				return 3;
			}
			if (moveToNodeInfo.NodeType != (int)NodeType.Container)
			{
				return 4;
			}
			if (StringHelper.FoundCharInArr(nodeInfo.ArrChildID, moveToNodeInfo.NodeID.ToString()))
			{
				return 5;
			}
			if (ExistsNodeName(moveToNodeInfo.NodeID.ToInt32(), nodeInfo.NodeName))
			{
				return 6;
			}
			if (ExistsNodeDir(moveToNodeInfo.NodeID.ToInt32(), nodeInfo.NodeDir))
			{
				return 7;
			}
			return 0;
		}
		/// <summary>
		/// 节点合并：合并两个节点下的信息到一个节点中，并返回不同的错误状态值，返回0代表成功。
		/// 返回值：调用WriteNodesUniteMessage（）方法显示
		/// </summary>
		/// <param name="nodeId">被合并的节点，合并成功后会被删除</param>
		/// <param name="targetNodeId">合并的目标节点</param>
		/// <returns></returns>
		public int NodesUnite(int nodeId, int targetNodeId)
		{
			if (nodeId <= 0)
			{
				return 1;
			}
			if (targetNodeId <= 0)
			{
				return 2;
			}
			if (nodeId == targetNodeId)
			{
				return 3;
			}
			var nodeById = GetNodeById(targetNodeId);
			if (nodeById==null)
			{
				return 4;
			}
			if (nodeById.Child > 0)
			{
				return 5;
			}
			if (nodeById.NodeType != (int)(NodeType.Container))
			{
				return 6;
			}
			var cacheNodeById = GetCacheNodeById(nodeId);
			if (cacheNodeById==null)
			{
				return 7;
			}
			if (StringHelper.FoundCharInArr(cacheNodeById.ArrChildID, targetNodeId.ToString()))
			{
				return 8;
			}
			_CommonInfoServiceApp.Update("NodeId = @NodeId", "NodeId IN @ids", new { NodeId = targetNodeId, ids = StringHelper.GetArrayBySplit<int>(cacheNodeById.ArrChildID).ToArray() });
			Delete(cacheNodeById.NodeID);
			RemoveCacheAllNodeInfo();
			return 0;
		}
		/// <summary>
		/// 批量移动节点时根据错误号返回错误消息 :找不到指定的节点或者已经被删除 节点移动失败
		/// </summary>
		/// <param name="errorNum"></param>
		/// <returns></returns>
		public string WriteMessageByErrorNum(int errorNum)
		{
			string str = string.Empty;
			switch (errorNum)
			{
				case 0:
					return str;

				case 1:
					return "找不到指定的节点或者已经被删除！";

				case 2:
					return "要移动节点和目标节点相同，无需移动！";

				case 3:
					return "目标节点与当前父节点相同，无需移动！";

				case 4:
					return "不能指定外部节点为所属节点！";

				case 5:
					return "不能指定该节点的下属节点作为所属节点！";

				case 6:
					return "目标节点的子节点中已经存在与此节点名称相同的节点，不能移动！";

				case 7:
					return "目标节点的子节点中是否已经存在与此节点目录相同的节点，不能移动！";
			}
			return "节点移动失败！";
		}
		/// <summary>
		/// 合并节点时根据错误号生成错误消息
		/// </summary>
		/// <param name="errorType"></param>
		/// <returns></returns>
		public string WriteNodesUniteMessage(int errorType)
		{
			string str = string.Empty;
			switch (errorType)
			{
				case 0:
					return str;

				case 1:
					return "未指定要合并的节点！";

				case 2:
					return "未指定目标节点！";

				case 3:
					return "要合并的节点与目标节点相同，请不要在相同节点内进行操作！";

				case 4:
					return "目标节点不存在，可能已经被删除！";

				case 5:
					return "目标节点中含有子节点，不能合并！";

				case 6:
					return "目标节点是专题、单个页面或外部节点！";

				case 7:
					return "找不到指定的节点，可能已经被删除！";

				case 8:
					return "不能将一个节点合并到其下属子节点中！";
			}
			return "节点合并失败！";
		}
		#endregion

		#region 生成节点导航
		/// <summary>
		/// 生成节点导航：根节点》父节点》节点
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public string ShowNodesAndRootNavigation(int nodeId)
		{
			return ShowNodeNavigation(nodeId, 2, string.Empty);
		}
		/// <summary>
		/// 生成节点导航：根节点》父节点
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public string ShowParentNodesNavigation(int nodeId)
		{
			return ShowNodeNavigation(nodeId, 1, string.Empty);
		}
		/// <summary>
		/// 生成节点导航，用于后台管理页面：根节点》父节点》《a》节点《/a》
		/// </summary>
		/// <param name="nodeId">节点导航中最尾端的节点ID</param>
		/// <returns></returns>
		public string ShowNodeNavigation(int nodeId)
		{
			return ShowNodeNavigation(nodeId, 0, string.Empty);
		}
		/// <summary>
		/// 生成节点导航，用于后台管理页面：根节点》父节点》《a》节点《/a》
		/// </summary>
		/// <param name="nodeId">节点导航中最尾端的节点ID</param>
		/// <param name="navigation">A标签的链接地址，留空为“/Admin/Contents/ContentManage”</param>
		/// <returns></returns>
		public string ShowNodeNavigation(int nodeId, string navigation)
		{
			return ShowNodeNavigation(nodeId, 0, navigation);
		}
		/// <summary>
		/// 生成节点导航，用于后台管理页面
		/// </summary>
		/// <param name="nodeId">节点导航中最尾端的节点ID</param>
		/// <param name="type">0：生成A标签</param>
		/// <param name="navigation">A标签的链接地址，留空为“/Admin/Contents/ContentManage”</param>
		/// <returns></returns>
		private string ShowNodeNavigation(int nodeId, int type, string navigation)
		{
			if (string.IsNullOrEmpty(navigation))
			{
				navigation = "/Admin/Contents/ContentManage";
			}
			NodesEntity cacheNodeById = GetCacheNodeById(nodeId);
			if (cacheNodeById==null)
			{
				return string.Empty;
			}
			IList<NodesEntity> nodesListInParentPath = GetNodesListInParentPath(cacheNodeById.ParentPath);
			StringBuilder builder = new StringBuilder();
			if (nodesListInParentPath.Count > 0)
			{
				foreach (NodesEntity info2 in nodesListInParentPath)
				{
					if (builder.Length > 0)
					{
						builder.Append(" >> ");
					}
					if (type == 0)
					{
						builder.Append(string.Concat(new object[] { "<a href='", navigation, "?NodeID=", info2.NodeID, "&NodeName=", DataSecurity.UrlEncode(info2.NodeName), "'>" }));
						builder.Append(DataSecurity.HtmlEncode(info2.NodeName));
						builder.Append("</a>");
					}
					else
					{
						builder.Append(DataSecurity.HtmlEncode(info2.NodeName));
					}
				}
			}
			if ((type == 0) || (type == 2))
			{
				if (builder.Length > 0)
				{
					builder.Append(" >> ");
				}
				builder.Append(DataSecurity.HtmlEncode(cacheNodeById.NodeName));
			}
			return builder.ToString();
		}
		#endregion

		#region 删除缓存
		/// <summary>
		/// 删除所有节点的缓存信息
		/// </summary>
		public void RemoveCacheAllNodeInfo()
		{
			CacheHelper.CacheServiceProvider.RemoveCacheRegex(@"CK_Content_NodeInfo_NodeId_\S*");
		}
		/// <summary>
		/// 删除指定节点的缓存信息
		/// </summary>
		/// <param name="nodeId"></param>
		public void RemoveCacheByNodeId(int nodeId)
		{
			CacheHelper.CacheServiceProvider.Remove("CK_Content_NodeInfo_NodeId_" + nodeId.ToString());
		}
		#endregion

		#region 其他
		/// <summary>
		/// 生成节点目录树，用于管理后台
		/// </summary>
		/// <param name="depth"></param>
		/// <param name="parentPath"></param>
		/// <param name="nextId"></param>
		/// <param name="child"></param>
		/// <returns></returns>
		public string GetTreeLine(int depth, string parentPath, int nextId, int child)
		{
			StringBuilder builder = new StringBuilder(string.Empty);
			string strParentPath = DataSecurity.FilterBadChar(parentPath);
			string strBasePath = Utility.GetBasePath();
			if (depth > 0)
			{
				for (int i = 1; i <= depth; i++)
				{
					if (i == depth)
					{
						if (nextId > 0)
						{
							builder.Append("<img src='" + strBasePath + "images/Node/tree_line1.gif' width='17' height='16' valign='abvmiddle' />");
						}
						else
						{
							builder.Append("<img src='" + strBasePath + "images/Node/tree_line2.gif' width='17' height='16' valign='abvmiddle' />");
						}
					}
					else if (GetNextIdByDepth(i, strParentPath) > 0)
					{
						builder.Append("<img src='" + strBasePath + "images/Node/tree_line3.gif' width='17' height='16' valign='abvmiddle' />");
					}
					else
					{
						builder.Append("<img src='" + strBasePath + "images/Node/tree_line4.gif' width='17' height='16' valign='abvmiddle' />");
					}
				}
			}
			if (child > 0)
			{
				builder.Append("<img src='" + strBasePath + "images/Node/tree_folder4.gif' width='15' height='15' valign='abvmiddle' />");
			}
			else
			{
				builder.Append("<img src='" + strBasePath + "images/Node/tree_folder3.gif' width='15' height='15' valign='abvmiddle' />");
			}
			if (depth == 0)
			{
				//builder.Append("<b>");
			}
			return builder.ToString();
		}
		/// <summary>
		/// 获取指定节点的子节点数组词典(NodeID与ArrChildID的对照表)
		/// </summary>
		/// <param name="parentPath">节点ID，多个ID用“,”分割</param>
		/// <returns></returns>
		public Dictionary<int, string> GetParentPathArrChildId(string parentPath)
		{
			if (DataValidator.IsValidId(parentPath))
			{
				Expression<Func<NodesEntity, bool>> predicate = p => true;
				var arrNodeID = parentPath.Split(',');
				predicate = predicate.And(p => arrNodeID.Contains(p.NodeID.ToString()));
				var result = m_repository.GetScalar<dynamic>(p => new { p.NodeID, p.ArrChildID }, predicate);
				Dictionary<int, string> dict = new Dictionary<int, string>();
				foreach (dynamic item in result)
				{
					dict.Add(item.NodeID, item.ArrChildID);
				}
			}
			return null;
		}
		/// <summary>
		/// 根据传入的参数，生成类似“（子节点数量） [节点目录名称]”的字符串。
		/// 生成节点树时附加的节点信息
		/// </summary>
		/// <param name="child">子节点数</param>
		/// <param name="nodeType">节点类型</param>
		/// <param name="nodeDir">节点目录</param>
		/// <returns></returns>
		public string GetNodeDir(int child, NodeType nodeType, string nodeDir)
		{
			StringBuilder builder = new StringBuilder();
			if (child > 0)
			{
				builder.Append("（");
				builder.Append(child);
				builder.Append("）");
			}
			if (NodeType.Link == nodeType)
			{
				builder.Append(" <font color=blue>（外）</font>");
			}
			else if (!string.IsNullOrEmpty(nodeDir))
			{
				builder.Append(" [");
				builder.Append(nodeDir);
				builder.Append("]");
			}
			return builder.ToString();
		}
		/// <summary>
		/// 得到使用指定模型的节点名称表（表结构：NodeID、NodeName）
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="nodeType"></param>
		/// <returns></returns>
		public DataTable GetNodeNameByModelId(int modelId, NodeType nodeType)
		{
			DataTable table = new DataTable();
			table.Columns.Add("NodeID");
			table.Columns.Add("NodeName");
			string tableName = "NodesModelTemplate R INNER JOIN Nodes N ON R.NodeID = N.NodeID";
			string strWhere = "R.ModelId = @ModelId AND N.NodeType = @NodeType";
			object param = new { ModelId = modelId, NodeType = (int)nodeType };
			var result = _NodesModelTemplateRepository.GetAllData<dynamic>(tableName, strWhere, param, "N.NodeID, N.NodeName");
			foreach (dynamic item in result)
			{
				DataRow row = table.NewRow();
				row["NodeID"] = item.NodeID;
				row["NodeName"] = item.NodeName;
				table.Rows.Add(row);
			}
			return table;
		}
		#endregion
	}
}
